package com.dk.rocltx;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dk.pojo.user.TbUser;
import com.dk.service.integral.IntegralData;
import com.dk.service.integral.IntegralService;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;

@RocketMQTransactionListener(txProducerGroup = "integral")
public class RockeMQTxListhenner implements RocketMQLocalTransactionListener {
    @Autowired
    private RedisTemplate redisTemplate;
    @Reference
    private IntegralService integralService;
    /**
     * 成功接收事物消息
     * @param message
     * @param o
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        //将本地事物执行状态return到MQ服务，并且保存到redis备份（网络延迟，MQ服务产生回调的时候 可以从redis中获取）
        try {
            //业务处理
            IntegralData integralData = (IntegralData) message.getPayload();
            TbUser user = (TbUser) SecurityUtils.getSubject().getPrincipal();
            Long userId = user.getId();
            int i = integralService.inserIntegral(integralData,userId);
            //int i = 9 / 0;
        } catch (Exception e) {
            //处理异常返回ROLLBACK
            redisTemplate.opsForValue().set(message.getHeaders().get("TRANSACTION_ID"), "2");
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        //处理成功返回COMMIT
        redisTemplate.opsForValue().set(message.getHeaders().get("TRANSACTION_ID"), "1");
        return RocketMQLocalTransactionState.COMMIT;
    }

    /**
     * 回查
     * @param message
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        //通过事务id获取 redis中 对应的本地事务执行状态
        String status = (String) redisTemplate.opsForValue().
                get(message.getHeaders().get("TRANSACTION_ID").toString());
        if ("1".equals(status)) {
            return RocketMQLocalTransactionState.COMMIT;
        } else if ("2".equals(status)) {
            //继续处理，或者直接回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        } else {
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}
